﻿#include <iostream>
#include <fstream>
#include <winsock2.h>
#include <unistd.h>

#define PORT 9999
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024
void Error(const std::string &message);
int main()
{
#ifndef SET_TERMINAL_CODE
  SetConsoleOutputCP(65001);
#endif
  WSADATA wsadata;
  WSAStartup(MAKEWORD(2, 2), &wsadata);
  // step01:创建服务端socket
  SOCKET sock_serv = socket(PF_INET, SOCK_STREAM, 0);
  if (sock_serv == -1)
    Error("socket() error!");

  // step02:设置监听套接字的IP地址和端口号
  sockaddr_in serverAddr{};
  serverAddr.sin_family = AF_INET;
  serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  serverAddr.sin_port = htons(PORT);
  if (bind(sock_serv, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
  {
    closesocket(sock_serv);
    Error("bind() error!");
  }

  // step03:进入等待请求连接状态
  if (listen(sock_serv, 1) == -1)
  {
    closesocket(sock_serv);
    Error("listen() error!");
  }
  std::cout << "listen() ok ..." << std::endl;

  sockaddr_in clientAddr{};
  int clientAddrLen = sizeof(clientAddr);
  ssize_t total;
  for (int i = 0; i < 10; i++)
  {
    std::cout << "client " << i + 1 << "..." << std::endl;
    // step04:进入数据传输阶段，接受客户端连接
    int sock_clnt = accept(sock_serv, (struct sockaddr *)&clientAddr, &clientAddrLen);
    if (sock_clnt == -1)
    {
      closesocket(sock_serv);
      Error("accept() error!");
    }
    std::cout << "accept() ok ..." << std::endl;
    total = 0;
    int bytesRead{0};
    // step05:传输数据，接收文件数据
    char buffer[BUFFER_SIZE];
    std::ofstream outputFile;
    outputFile.open("../rescource.pdf", std::ios::binary);
    if (!outputFile.is_open())
    {
      closesocket(sock_clnt);
      closesocket(sock_serv);
      Error("Failed to open file!");
    }
    while ((bytesRead = recv(sock_clnt, buffer, BUFFER_SIZE, 0)) > 0)
    {
      if (bytesRead == -1)
        Error("接收数据失败");
      outputFile.write(buffer, bytesRead);
      // fwrite(buffer, 1, bytesRead, outputFile);
      total += bytesRead;
    }
    send(sock_clnt, "客户端成功接收文件数据！", BUFFER_SIZE, 0);

    // fclose(outputFile);
    outputFile.close();
    std::cout << "total size:" << total << std::endl;
    // 关闭连接
    closesocket(sock_clnt);
  }
  closesocket(sock_serv);
  WSACleanup();
  return 0;
}
void Error(const std::string &message)
{
  std::cout << message << std::endl;
  exit(-1);
}
